package com.downloader;

/**
 * Copyright (c) 2011 Mujtaba Hassanpur.
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */


import java.io.*;
import java.net.*;

import android.os.Message;

import com.mobilnaElka.AppConsts;
import com.mobilnaElka.activities.R;
import com.mobilnaElka.activities.search.SearchTabActivity;

/**
 * Downloads a file in a thread. Will send messages to the
 * AndroidFileDownloader activity to update the progress bar.
 */
public class DownloaderThread extends Thread
{
        // constants
        private static final int DOWNLOAD_BUFFER_SIZE = 4096;
        
        // instance variables
        private SearchTabActivity parentActivity;
        private String downloadUrl;
        private String filename;
        
        /**
         * Instantiates a new DownloaderThread object.
         * @param parentActivity Reference to SecondTab activity.
         * @param inUrl String representing the URL of the file to be downloaded.
         * @param surname 
         */
        public DownloaderThread(SearchTabActivity inParentActivity, String inUrl, String filename)
        {
                downloadUrl = "";
                this.filename = filename;
                if(inUrl != null)
                {
                        downloadUrl = inUrl;
                }
                parentActivity = inParentActivity;
        }
        
        /**
         * Connects to the URL of the file, begins the download, and notifies the
         * SecondTab activity of changes in state. Writes the file to
         * the root of the SD card.
         */
        @Override
        public void run()
        {
                URL url;
                URLConnection conn;
                int fileSize;
                String fileName;
                BufferedInputStream inStream;
                BufferedOutputStream outStream;
                File outFile;
                FileOutputStream fileStream;
                Message msg;
                
                // we're going to connect now
                msg = Message.obtain(parentActivity.activityHandler,
                                SearchTabActivity.MESSAGE_CONNECTING_STARTED,
                                0, 0, downloadUrl);
                parentActivity.activityHandler.sendMessage(msg);
                
                try
                {
                        url = new URL(downloadUrl);
                        conn = url.openConnection();
                        conn.setUseCaches(false);
                        fileSize = conn.getContentLength();
                        
                        // get the filename
                        fileName=filename;
                        
                        // notify download start
                        int fileSizeInKB = fileSize / 1024;
                        msg = Message.obtain(parentActivity.activityHandler,
                                        SearchTabActivity.MESSAGE_DOWNLOAD_STARTED,
                                        fileSizeInKB, 0, fileName);
                        parentActivity.activityHandler.sendMessage(msg);
                        
                        // start download
                        inStream = new BufferedInputStream(conn.getInputStream());
                        outFile = new File(AppConsts.STUFFS_DIR+ "/" + fileName);
                        fileStream = new FileOutputStream(outFile);
                        outStream = new BufferedOutputStream(fileStream, DOWNLOAD_BUFFER_SIZE);
                        byte[] data = new byte[DOWNLOAD_BUFFER_SIZE];
                        int bytesRead = 0, totalRead = 0;
                        while(!isInterrupted() && (bytesRead = inStream.read(data, 0, data.length)) >= 0)
                        {
                                outStream.write(data, 0, bytesRead);
                                
                                // update progress bar
                                totalRead += bytesRead;
                                int totalReadInKB = totalRead / 1024;
                                msg = Message.obtain(parentActivity.activityHandler,
                                                SearchTabActivity.MESSAGE_UPDATE_PROGRESS_BAR,
                                                totalReadInKB, 0);
                                parentActivity.activityHandler.sendMessage(msg);
                        }
                        
                        outStream.close();
                        fileStream.close();
                        inStream.close();
                        
                        if(isInterrupted())
                        {
                                // the download was canceled, so let's delete the partially downloaded file
                                outFile.delete();
                        }
                        else
                        {
                                // notify completion
                                msg = Message.obtain(parentActivity.activityHandler,
                                                SearchTabActivity.MESSAGE_DOWNLOAD_COMPLETE);
                                parentActivity.activityHandler.sendMessage(msg);
                        }
                }
                
                catch(MalformedURLException e)
                {
                        String errMsg = parentActivity.getString(R.string.error_message_bad_url);
                        msg = Message.obtain(parentActivity.activityHandler,
                                        SearchTabActivity.MESSAGE_ENCOUNTERED_ERROR,
                                        0, 0, errMsg);
                        parentActivity.activityHandler.sendMessage(msg);
                }
                catch(FileNotFoundException e)
                {
                        String errMsg = parentActivity.getString(R.string.error_message_file_not_found);
                        msg = Message.obtain(parentActivity.activityHandler,
                                        SearchTabActivity.MESSAGE_ENCOUNTERED_ERROR,
                                        0, 0, errMsg);
                        parentActivity.activityHandler.sendMessage(msg); 
                }
                catch(Exception e)
                {
                        String errMsg = parentActivity.getString(R.string.error_message_general);
                        msg = Message.obtain(parentActivity.activityHandler,
                                        SearchTabActivity.MESSAGE_ENCOUNTERED_ERROR,
                                        0, 0, errMsg);
                        parentActivity.activityHandler.sendMessage(msg); 
                }
        }
        
}
